
import pprint 

CUBE_CONFIG_FILE_PATH = "oskar_input.txt"

GO_X_POSITIVE = 0 
GO_X_NEGATIVE = 1
GO_Y_POSITIVE = 2
GO_Y_NEGATIVE = 3
GO_Z_POSITIVE = 4
GO_Z_NEGATIVE = 5

ACTION_TUPPLES = {
                  GO_X_POSITIVE : ( 1, 0, 0), 
                  GO_X_NEGATIVE : ( -1, 0, 0),
                  GO_Y_POSITIVE : ( 0, 1, 0), 
                  GO_Y_NEGATIVE : ( 0, -1, 0),
                  GO_Z_POSITIVE : ( 0, 0, 1), 
                  GO_Z_NEGATIVE : ( 0, 0, -1)                  
}


class Cube():   
    def __init__( self, config_file_path ):
        config_file = open( config_file_path, "r" )
        
        self.__getDimensions    ( config_file )
        self.__getSourcePosition( config_file )
        self.__getDestPosition  ( config_file )
        self.__getXYFlags       ( config_file )
        self.__getYZFlags       ( config_file )
        self.__getZXFlags       ( config_file )
        
#        pprint.pprint( self.xy_flags )
#        print( "#" * 30)
#        pprint.pprint( self.yz_flags )
#        print( "#" * 30)
#        pprint.pprint( self.zx_flags )
#        
    def __getDimensions( self, config_file ):
        self.x_dim = int( config_file.readline() )
        self.y_dim = int( config_file.readline() )
        self.z_dim = int( config_file.readline() )
        self.empty_line = config_file.readline()
    
    
    def __getSourcePosition(self, config_file):
        source_pos = config_file.readline().split()
        source_pos_as_ints = map( int, source_pos )
        self.source_pos = tuple( source_pos_as_ints ) 
    
    def __getDestPosition(self, config_file):
        dest_pos = config_file.readline().split()        
        self.empty_line = config_file.readline()
        
        dest_pos_as_ints = map( int, dest_pos )
        self.dest_pos = tuple( dest_pos_as_ints )
        
    def __getXYFlags(self, config_file):
        self.xy_flags = []
        for line_index in range( self.z_dim ): #@UnusedVariable
            flags = config_file.readline().split()
            self.xy_flags.append( flags )
        self.empty_line = config_file.readline()
    
    def __getYZFlags(self, config_file):
        self.yz_flags = []
        for line_index in range( self.z_dim ): #@UnusedVariable
            flags = config_file.readline().split()
            self.yz_flags.append( flags )
        self.empty_line = config_file.readline()

    def __getZXFlags(self, config_file):
        self.zx_flags = []
        for line_index in range( self.z_dim ): #@UnusedVariable
            flags = config_file.readline().split()
            self.zx_flags.append( flags )
        self.empty_line = config_file.readline()
        

    def __initBacktrackingMatrix( self ): 
        self.__been_there = []
        for x_index in range( self.x_dim ): #@UnusedVariable
            yz_filled_with_falses = []
            for y_index in range( self.y_dim ): #@UnusedVariable
                z_filled_with_falses = []
                for z_index in range( self.z_dim ): #@UnusedVariable
                    z_filled_with_falses.append( False )
                yz_filled_with_falses.append( z_filled_with_falses[:] )
                
            self.__been_there.append( yz_filled_with_falses[:] )     

    def __initSolveVariables(self):
        self.__initBacktrackingMatrix()
        self.soloution_path  = [ self.source_pos ]
        self.soloution_steps = []
        

    def __markPositionAsVisited(self, current_pos):
        x = current_pos[ 0 ]
        y = current_pos[ 1 ]
        z = current_pos[ 2 ]
        self.__been_there[ x ][ y ][ z ] = True
    
    

    def __markPositionAsClear(self, current_pos):
        x = current_pos[ 0 ]
        y = current_pos[ 1 ]
        z = current_pos[ 2 ]
        self.__been_there[ x ][ y ][ z ] = False
    
    

    def __calcNextPosition(self, current_pos, action):
        action_movement = ACTION_TUPPLES[ action ]
        next_x = current_pos[ 0 ] + action_movement[ 0 ]
        next_y = current_pos[ 1 ] + action_movement[ 1 ]
        next_z = current_pos[ 2 ] + action_movement[ 2 ]
        
        return ( next_x, next_y, next_z )
        

    def __isLegalPositionAndNotBeenThere(self, next_pos):
        x = next_pos[ 0 ]
        y = next_pos[ 1 ]
        z = next_pos[ 2 ]
        
        if self.__been_there[ x ][ y ][ z ]:
            return False
        
        return self.isLegalPosition( next_pos )
    
    def __doSolve( self, current_pos  ):
        print( "Current Pos:" + str( current_pos ) )
        if current_pos == self.dest_pos:
            return True
        
        self.__markPositionAsVisited( current_pos )
        for action in ACTION_TUPPLES.keys():
            next_pos = self.__calcNextPosition( current_pos, action )
            if self.__isLegalPositionAndNotBeenThere( next_pos ):
                print( "Trying to perform action " + str( action ) )
                self.soloution_steps.append( action )
                self.soloution_path.append( next_pos )
                if True == self.__doSolve( next_pos ):
                    return True  #We found a soloution going this way
                else:#retrack this step
                    self.soloution_steps.pop()
                    self.soloution_path.pop()
        
        print( "###### Backtracking!!!")    
        self.__markPositionAsClear( current_pos )
        return False #no soloution was found...
                    
    def solve( self ):
        self.__initSolveVariables()   
        
        if True == self.__doSolve( self.source_pos ):
            return self.soloution_steps
        else:
            return None  

    def isLegalPosition( self, pos ):
        x = pos[ 0 ]
        y = pos[ 1 ]
        z = pos[ 2 ]
        
        if ( self.xy_flags[ y ][ x ] ) != '0':
            return False
        if self.yz_flags[ z ][ y ] != '0':
            return False
        if self.zx_flags[ x ][ z ] != '0':
            return False
        
        return True

def main():
    print( "hi2" )
    cube = Cube( CUBE_CONFIG_FILE_PATH )
    #soloution = cube.solve()
    print( cube.isLegalPosition( (1,1,1) ) )
    print( cube.isLegalPosition( (1,3,3) ) )
    print( cube.isLegalPosition( (2,3,3) ) )
    
    soloution = cube.solve()
    pprint.pprint( soloution )
    f = open( 'sol.txt', "w")
    f.write( str(soloution) )
    f.close()


if __name__ == "__main__":
    main()
    